package com.example.tass.controller;

import cn.tass.SRJ1933.devices.inf.TassSignServerApi;
import cn.tass.SRJ1933.devices.params.request.p7Sign.GetInfoFromP7SignRequest;
import cn.tass.SRJ1933.devices.params.request.p7Sign.P7SignExternalRequest;
import cn.tass.SRJ1933.devices.params.request.p7Sign.P7SignRequest;
import cn.tass.SRJ1933.devices.params.request.p7Sign.VerifyP7SignRequest;
import cn.tass.SRJ1933.devices.params.response.cert.ListRootCertIdsResponse;
import cn.tass.SRJ1933.devices.params.response.p7Sign.GetInfoFromP7SignResponse;
import cn.tass.SRJ1933.devices.params.response.p7Sign.P7SignExternalResponse;
import cn.tass.SRJ1933.devices.params.response.p7Sign.P7SignResponse;
import cn.tass.SRJ1933.devices.params.response.p7Sign.VerifyP7SignResponse;
import cn.tass.exceptions.TAException;
import com.example.tass.common.ResultMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class P7Sign_3_3 {
    private static String printFormat = "错误码[%d]\n错误消息[%s]\n接口结果： %s\n";
    private static final Logger logger = LoggerFactory.getLogger(P7Sign_3_3.class);
    private TassSignServerApi signServerApi;

    public P7Sign_3_3(TassSignServerApi signServerApi) {
        this.signServerApi = signServerApi;
    }

    // 3.3.1 编制P7签名（内部密钥）（带原文和不带原文）
    @GetMapping(value = "/p7Sign")
    public ResultMessage p7Sign(@RequestBody P7SignRequest request) {
        try {
            P7SignResponse response = signServerApi.p7Sign(request.getKeyId(), request.getKeyIdType(), request.getKeyAccessCode(),
                    request.getSm2UserID(), request.getAlgorithm(), request.getData(), request.getDataType(), request.isDetach());
            if (response.getCode() != 0) {
                logger.error(response.getMsg());
                return ResultMessage.newFailureResult(response.getMsg());
            } else {
                System.out.println("生成对称密钥（生成对称密钥 – 明文返回）： " + String.format(printFormat, response.getCode(), response.getMsg(), response.getSign()));
                return ResultMessage.newSuccessResult(response.getSign());
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    // PKCS7Attach验签(带原文和不带原文)
    @GetMapping(value = "/pkcs7AttachVerify")
    public ResultMessage pkcs7AttachVerify(@RequestBody VerifyP7SignRequest request) {
        try {
            VerifyP7SignResponse response = signServerApi.verifyP7Sign(request.getData(), request.getDataType(), request.getSign(), request.getIsDetach(), request.getSm2UserID(),
                    request.getVerifyLevel(), request.getIsReturnCert(), request.getIsReturnData());
            if (response.getCode() != 0) {
                logger.error(response.getMsg());
                return ResultMessage.newFailureResult(response.getMsg());
            } else {
                System.out.println("生成对称密钥（生成对称密钥 – 明文返回）： " + String.format(printFormat, response.getCode(), response.getMsg(), response.getData()));
                ResultMessage resultMessage = ResultMessage.newSuccessResult();
                resultMessage.setData(response);
                return resultMessage;
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    // 3.3.2编制P7签名（外部私钥和外部证书）
    @GetMapping(value = "/p7SignExternal")
    public ResultMessage p7SignExternal(@RequestBody P7SignExternalRequest request) {
        try {
            P7SignExternalResponse response = signServerApi.p7SignExternal(request.getPrivKey(), request.getAlgorithm(), request.getData(), request.getDataType(),
                    request.isDetach(), request.getCert(), request.getSm2UserID(), request.isIncludeAuthAttr(), request.getAuthAttrList(),
                    request.getNoAuthAttrList());
            if (response.getCode() != 0) {
                logger.error(response.getMsg());
                return ResultMessage.newFailureResult(response.getMsg());
            } else {
                System.out.println("生成对称密钥（生成对称密钥 – 明文返回）： " + String.format(printFormat, response.getCode(), response.getMsg(), response.getSign()));
                return ResultMessage.newSuccessResult(response.getSign());
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }
    
    // 3.3.3.1验证裸签名（外部私钥密文）
    @GetMapping(value = "/verifyP7Sign")
    public ResultMessage verifyP7Sign(@RequestBody VerifyP7SignRequest request){
        try {
            VerifyP7SignResponse response = signServerApi.verifyP7Sign(request.getData(), request.getDataType(), request.getSign(), request.getIsDetach());
            if (response.getCode() != 0) {
                logger.error(response.getMsg());
                return ResultMessage.newFailureResult(response.getMsg());
            } else {
                System.out.println("生成对称密钥（生成对称密钥 – 明文返回）： " + String.format(printFormat, response.getCode(), response.getMsg(), response.getData()));
                ResultMessage resultMessage = ResultMessage.newSuccessResult();
                resultMessage.setData(response);
                return resultMessage;
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }

    // 3.3.4获取P7签名信息
    @GetMapping(value = "/getInfoFromP7Sign")
    public ResultMessage getInfoFromP7Sign(@RequestBody GetInfoFromP7SignRequest request) {
        try {
            GetInfoFromP7SignResponse response = signServerApi.getInfoFromP7Sign(request.getSign(), request.getInfoType());
            if (response.getCode() != 0) {
                logger.error(response.getMsg());
                return ResultMessage.newFailureResult(response.getMsg());
            } else {
                System.out.println("生成对称密钥（生成对称密钥 – 明文返回）： " + String.format(printFormat, response.getCode(), response.getMsg(), response.getSign()));
                ResultMessage resultMessage = ResultMessage.newSuccessResult();
                resultMessage.setData(response);
                return resultMessage;
            }
        } catch (TAException e) {
            throw new RuntimeException(e);
        }
    }
}
